/*
 * UpperCase.java
 *
 * Created on 2011-7-14 01:48:49 pm
 */
package com.wsleo.jblog.freemarker.directive.util;

import java.io.IOException;
import java.io.Writer;
import java.util.Map;

import freemarker.template.TemplateBooleanModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateTransformModel;

@SuppressWarnings("rawtypes")
public class UpperCase implements TemplateTransformModel {
    
    private static final String INIT_CAPITAL = "init_capital";
    
    public static final UpperCase INSTANCE = new UpperCase();

    public Writer getWriter(final Writer out, Map args) throws TemplateModelException, IOException {
        
        boolean initCapital = false;
        if (args != null) {
            try {
                TemplateBooleanModel flag = (TemplateBooleanModel)args.get(INIT_CAPITAL);
                if (flag != null)
                    initCapital = flag.getAsBoolean();
            } catch (ClassCastException e) {
                throw new TemplateModelException("Expecting boolean argument to " + INIT_CAPITAL);
            }
        }
        return new UpperCaseWriter(out, initCapital);
    }
    
    private static class UpperCaseWriter extends Writer {
        private final Writer out;
        private final boolean initCapital;
        
        public UpperCaseWriter(final Writer out, boolean initCapital) {
            this.out = out;
            this.initCapital = initCapital;
        }

        @Override
        public void write(char[] cbuf, int off, int len) throws IOException {
            if (initCapital) {
                int j = 0;
                if (!"".equals(cbuf[0])) {
                    cbuf[0] = Character.toUpperCase(cbuf[0]);
                    j = 1;
                }
                for (int i = j; i < len; i++) {
                    if ("".equals(cbuf[i]) && !"".equals(cbuf[i + 1])) {
                        cbuf[i + 1] = Character.toUpperCase(cbuf[i + 1]);
                    }
                }
                out.write(cbuf, off, len);
            } else {
                out.write(new String(cbuf).toUpperCase(), off, len);
            }
        }

        @Override
        public void flush() throws IOException {
            
        }

        @Override
        public void close() throws IOException {
            
        }
    }
}
